package com.itheima.controller;


//此处是菜品表现层

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.common.R;
import com.itheima.dto.DishDto;
import com.itheima.entity.Category;
import com.itheima.entity.Dish;
import com.itheima.entity.DishFlavor;
import com.itheima.service.IDishFlavorService;
import com.itheima.service.imlp.CategoryServiceImpl;
import com.itheima.service.imlp.DishServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {

//      接口2：添加菜品【复杂】
//      备注：涉及表 Dish【菜品表】、Dish_flavor【菜品口味表】
//      请求url地址：/dish
//      请求方式：POST
//      请求参数：JSON格式数据 ---> 用什么对象封装  Dish  DishFlavor 都不是！用新的实体类 DishDto;

//    导入业务层
    @Autowired
    private DishServiceImpl dishService;
    
//    注入菜品分类
    @Autowired
    private CategoryServiceImpl categoryService;

//    注入菜品口味
    @Autowired
    private IDishFlavorService dishFlavorService;

//    注入redisTemplate
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;





//      接口四：分页查询菜品数据
//      请求url地址：/dish/page ?page=1&pageSize=10&name=白菜
//      请求方式：GET
//      请求参数：?page=1&pageSize=10&name=白菜

    @GetMapping("/page")
    public R<Page> page(Integer page,Integer pageSize,String name){
//        1先处理分页查询问题
        Page<Dish> dishPage = new Page<>(page,pageSize);
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotEmpty(name),Dish::getName,name);
        wrapper.orderByAsc(Dish::getId).orderByDesc(Dish::getUpdateTime);
        dishService.page(dishPage,wrapper);

//        2处理菜品分类问题
//        思路:
//        获得DTO表,DTO表中继承了Dish的全部属性,并扩展了菜品分类名称属性,
//        但是由于SQL数据库中没有同名的数据表,因此没有办法直接进行封装操作.
//        可以先封装Dish,再把Dish表中相同的数据赋值给DTO,再对DTO中,特有的属性进行赋值操作.
//        最后把DTO返回到前端页面上,前端页面根据DTO中的数据,进行展示

//        获得DTO page对象,用于对接Dish page
        Page<DishDto> dishDtoPage = new Page<>();
//        将dish复制给DTO,但是要排除数据内容,因为数据内容不相同,需要单独处理
        BeanUtils.copyProperties(dishPage,dishDtoPage,"records");
//        获得Dish的records对象,并进行处理.不使用DTO的原因是,DTO是一个空表,处理也没用
        List<Dish> records = dishPage.getRecords();
        List<DishDto> list = records.stream().map((dish) -> {
//            获取表中菜品分类的ID
            Long categoryId = dish.getCategoryId();
//            根据ID获取菜品分类对象,通过对象获得菜品对象名称,
//            此处可以调用菜品分类的业务层对象,通过对象方法,根据ID值查询到数据
            Category category = categoryService.getById(categoryId);
//            将该名称赋值给DTO中
            DishDto dishDto = new DishDto();
            if (category!=null){
                //            通过对象查询到菜品分类名称
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
//            由于DTO是空表,因此,还需要把Dish的内容赋值给DTO中
            BeanUtils.copyProperties(dish, dishDto);
//            返回dishDTO对象
            return dishDto;
        }).collect(Collectors.toList());

//        把处理好的数据赋值给dtoPage中
        dishDtoPage.setRecords(list);

        return R.success(dishDtoPage);

    }

//          接口五：修改菜品数据
//          接口1：根据id查询菜品数据，用于回显
//          请求url地址：/dish/1504708761831292929
//          请求方式：GET
//          请求参数：无
//          响应结果【格式统一】：R 对象

//    发给前端的内容要包含两个表的数据,因此此处使用DTO作为封装泛型

    @GetMapping("/{id}")
    public R<DishDto> dishGet(@PathVariable Long id){
        DishDto dishDto = dishService.queryWithFlavor(id);
        return R.success(dishDto);
    }

//      接口二：修改菜品
//      请求url地址：/dish
//      请求方式：PUT
//      请求参数：JSON格式的数据  ，使用DishDto封装
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
        dishService.updateWithFlavor(dishDto);
        //清空redis
        //定义清理的对象Key
        Set keys = redisTemplate.keys("dish_*");
        log.info("Ket:{}",keys);
        redisTemplate.delete(keys);
        return R.success("修改成功");
    }

    //新增
    @PostMapping
    public R<String> dishSave(@RequestBody DishDto dishDto){
        dishService.saveWithFlavor(dishDto);
        //清空redis
        //定义清理的对象Key
        String keys = "dish_" + dishDto.getCategoryId();
        log.info("Ket{}",keys);
        redisTemplate.delete(keys);
        return R.success("添加成功");
    }

//          接口4：根据分类id查询该分类下的所有菜品集合
//          请求url地址：/dish/list    ?categoryId=1397844263642378242
//          请求方式：GET
//          请求参数：?categoryId=1397844263642378242
//          响应结果【格式统一】：R<List<Dish>> 对象

    @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish){
//      定义dishDtos对象
        List<DishDto> dishDtos = null;
        //定义Key的值 dish_categoryId
        String Key = "dish_"+dish.getCategoryId();
        //根据Key查询数据，并返回Dto对象
        dishDtos = (List<DishDto>) redisTemplate.opsForValue().get(Key);
        //如果redis不为空则返回数据
        if (dishDtos!=null){
            return R.success(dishDtos);
        }
//        根据ID传输集合数据
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper();
        wrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId()).eq(Dish::getStatus,1);
        wrapper.orderByAsc(Dish::getSort);
//        此处查询Dish信息
        List<Dish> dishList = dishService.list(wrapper);

//    现在：     R<List<DishDto>>   返回的Dish集合中还需要有菜品的口味数据
//              DishDto【既包含菜品数据也包含菜品的口味数据】



//        此处要分别获取分类名称和菜品口味信息
          dishDtos = dishList.stream().map(dishs -> {
//            创建DTO，把dish的先赋值
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dishs, dishDto);

//            获取分类名称
            Long categoryId = dishs.getCategoryId();
            Category category = categoryService.getById(categoryId);
            String categoryName = category.getName();
            dishDto.setCategoryName(categoryName);

//            获取口味信息,根据ID找
            LambdaQueryWrapper<DishFlavor> wrapperFlavor = new LambdaQueryWrapper<>();
            wrapperFlavor.eq(DishFlavor::getDishId, dishs.getId());
            List<DishFlavor> DishFlavorList = dishFlavorService.list(wrapperFlavor);
            dishDto.setFlavors(DishFlavorList);
            return dishDto;
        }).collect(Collectors.toList());

        //如果redis中没有数据，则存入redis中
        redisTemplate.opsForValue().set(Key,dishDtos);
        return R.success(dishDtos);
    }
//      接口六：删除菜品接口[和批量删除用的是同一个接口]
//      请求url地址：/dish    ?ids=1504708761831292929,1504653856504483842
//      请求方式：DELETE
//      请求参数：?ids=1504708761831292929,1504653856504483842
//      响应结果【格式统一】：R 对象

    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids){
//        此处删除主要针对于两个表进行操作
        dishService.deleteWithFlavor(ids);
        return R.success("删除成功");
    }

//      接口七：起售/停售 批量起售/批量停售
//      请求url地址：/dish/status/1  ?ids=1504708761831292929,1504653856504483842,1413384757047271425
//      请求方式：POST
//      请求参数：?ids=1504708761831292929,1504653856504483842,1413384757047271425
//      响应结果【格式统一】：R 对象
    @PostMapping("/status/{id}")
    public R<String> status(@PathVariable Integer id,@RequestParam List<Long> ids){
        dishService.status(id,ids);
        return R.success("修改成功");
    }


}
